// 代理到现有文化青浦云后台 ajax 服务
// 添加跨域支持

const http = require('http');
const Koa = require('koa');
const axios = require('axios');

const app = new Koa();

// 所有配置集中写到此处
const config = {
  listen: {
    port: 2009,
  },
  targetPrefix: 'http://192.168.18.189:8081',
  rawResponse: true, // 启用将免去解析响应再重新序列化返回客户端的开销，不启用调式输出信息更清新
};

const PORT = config.listen.port || 60080;

const server = http.createServer(app.callback());
server.listen(PORT, () => {
  console.log(`listening at port:${PORT}`);
});

// 保证返回永远有跨域支持
app.use(async (ctx, next) => {
  ctx.set('Access-Control-Allow-Origin', '*');
  await next();
});


// 获取请求体，解析成 js 数据，目前看必须是第一个中间件


const getBackendForm = axios.create({
  timeout: 15 * 60 * 1000,
  responseType: config.rawResponse ? 'arraybuffer' : 'json',
  headers: {
    // 'Content-Type': 'application/x-www-form-urlencoded',
  },
});

const postBackendForm = axios.create({
  timeout: 15 * 60 * 1000,
  responseType: config.rawResponse ? 'arraybuffer' : 'json',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
});

const contentType = require('content-type');
const getRawBody = require('raw-body');

let counter = 0;
app.use(async (ctx, next) => {
  counter += 1;
  const reqNo = counter;
  console.log(`\nrequest.${reqNo} ${ctx.method} ${ctx.request.url}`);

  let body;
  if (ctx.method === 'POST') {
    body = await getRawBody(ctx.req, {
      length: ctx.req.headers['content-length'],
      limit: '1mb',
      encoding: contentType.parse(ctx.req).parameters.charset,
    });
  }
  console.log(ctx.method, body);

  const response = await (ctx.method === 'GET'
    ? getBackendForm.get(config.targetPrefix + ctx.request.url)
    : postBackendForm.post(config.targetPrefix + ctx.request.url, body)
  );

  console.log(`\nresponse.${reqNo} ${ctx.method} ${ctx.request.url}`);
  if (config.rawResponse) {
    console.log(response.data.slice(0, 20));
  } else {
    console.dir(response.data, {
      depth: 5,
      maxArrayLength: 3,
      breakLength: 80,
    });
  }
  ctx.body = response.data;
  ctx.type = 'application/json';
  await next();
});
